namespace PHSRAG.Insight21.FormsManagement.Controls
{
	using System;
	using System.Data;
	using System.Drawing;
	using System.Web;
	using System.Web.UI;
	using System.Web.UI.WebControls;
	using System.Web.UI.HtmlControls;
	using System.Collections;
	using PHSRAG.Insight21.CDS;

	/// <summary>
	///	ItemOptionEditor helps in adding new options or modifying existing ones, for a question. 
	/// </summary>
	public partial class ItemOptionEditor : System.Web.UI.UserControl
	{
		#region Constants
		private const string ItemOptionsSourceKey = "ItemOptionsKey_14FD15B1-D3C4-47ce-B376-4025A25EBB9E";
		private const string ColumnSNo = "SNo";
		private const string ColumnId = "ID";
		private const string ColumnOptionValue = "OptionValue";
		private const string ColumnOptionText = "OptionText";
		#endregion
		
		#region Instance Variables (private)
		private DataTable itemOptionsSource;
		private Policy.ICachePolicy		cachePolicy;
		private	Policy.ICachePolicy		pageCachePolicy;
		private bool isVersionDeployed;
		private QuestionnaireItem currentItem;
		#endregion
		
		#region Properties
		/// <summary>
		/// Gets or sets whether or not the version is deployed.
		/// </summary>
		public bool IsVersionDeployed
		{
			get { return isVersionDeployed; }
			set { isVersionDeployed = value; }
		}
		#endregion

		#region Events (page)
		/// <summary>
		/// Loads options, if any existing, into the grid.
		/// </summary>
		/// <param name="sender">Control that raised the event.</param>
		/// <param name="e">Arguments associated with the event.</param>
		protected void OnPageLoad(object sender, System.EventArgs e)
		{
			currentItem = (QuestionnaireItem)pageCachePolicy.GetCachedObject(Keys.QuestionnaireItemKey);
			if (!IsPostBack)
			{
				refDomain.Items.Add(new ListItem("--Select--", "0"));
				foreach(DataRow dr in RefCodes.GetDomains(Utility.DataAccess.ConnectionString).Rows)
				{
					string s = dr["RefDomain"].ToString();
					refDomain.Items.Add(new ListItem(s, s));
				}

				//The options source is built and cached irrespective of whether the QI 
				//is already designed to get options from refCodes because if the user
				//switches from ExplicitAnswers to RefCodeAnswers and then back to ExplicitAnswers then
				//all the previously entered answers are ready to be bound to the grid.
				CreateItemOptionsSource();
				ArrayList itemOptionsList = (ArrayList)pageCachePolicy.GetCachedObject(Keys.ItemOptionsKey);
				pageCachePolicy.UnCache(Keys.ItemOptionsKey);
				if (itemOptionsList.Count > 0)
					LoadItemOptions(itemOptionsList);
				else
					AddEmptyRows();
				BindItemOptions();
				pageCachePolicy.Cache(ItemOptionsSourceKey, itemOptionsSource);
				
				if (currentItem.OptionsRefDomain == null || currentItem.OptionsRefDomain == string.Empty)
				{
					refCodeAnswers.SelectedIndex = 1;
				}
				else
				{
					refCodeAnswers.SelectedIndex = 0;
					refDomain.SelectedValue = currentItem.OptionsRefDomain;
				}
				ToggleAnswerPanels();
				if (isVersionDeployed)
				{
					addRows.Enabled = false;
					refCodeAnswers.Enabled = false;
				}
			}
			else
			{
				itemOptionsSource = (DataTable)pageCachePolicy.GetCachedObject(ItemOptionsSourceKey);;
			}	
		}
		#endregion

		#region Web Form Designer generated code
		/// <summary>
		/// Page Initialization
		/// </summary>
		/// <param name="e">Arguments associated with the event.</param>
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
			pageCachePolicy = (Policy.ICachePolicy)Session[Policy.Names.PageCachePolicyKey];
			cachePolicy = (Policy.ICachePolicy)Session[Policy.Names.CachePolicyKey];
		}
		
		
		/// <summary>
		///		Required method for Designer support - do not modify
		///		the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.itemOptions.ItemCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.OnItemOptionsItemCommand);
			this.itemOptions.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.itemOptions_ItemDataBound);
			this.Load += new System.EventHandler(this.OnPageLoad);

		}
		#endregion

		#region Events (controls)
		/// <summary>
		/// Adds blank rows to the grid
		/// </summary>
		/// <param name="sender">Control that raised the event.</param>
		/// <param name="e">Arguments associated with the event.</param>
		protected void OnAddRowsClick(object sender, System.EventArgs e)
		{
			AddEmptyRows();
		}


		/// <summary>
		/// Registers a script that will pop up a new window to edit the option text.
		/// </summary>
		/// <param name="sender">Control that raised the event.</param>
		/// <param name="e">Arguments associated with the event.</param>
		private void OnItemOptionsItemCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			//Cache the text corresponding to the button on which the user clicks. 
			//Register a script that will pop up a new window and loads the FTBEditor.aspx
			Hashtable outgoingData = new Hashtable();
			outgoingData[Keys.OptionTextControlName] = ((TextBox)itemOptions.Items[e.Item.ItemIndex].FindControl("itemOptionText")).ClientID;
			outgoingData[Keys.OptionTextKey] =  ((TextBox)itemOptions.Items[e.Item.ItemIndex].FindControl("itemOptionText")).Text;
			pageCachePolicy.Cache(Keys.IncomingDataKey, outgoingData);

			if (e.CommandName == "FTB")
			{
				//Script for popup window that displays the attachment
				string script = "\n<script language=JavaScript id='FTBEditor'>\n" + 
					"var confirmWin = null; \n" +
					"confirmWin = window.open('../FormsManagement/FTBEditor.aspx', 'OptionTextEditor', 'width=800, height=600, status=no'); \n" +
					"</script>";

				if(!Page.ClientScript.IsClientScriptBlockRegistered("FTBEditor"))
				{
					Page.ClientScript.RegisterClientScriptBlock(GetType( ), "FTBEditor",script);
				}
			}
		}

		#endregion

		#region Private methods
		/// <summary>
		/// The ItemOptions source is used as the datasource for the the Item Options grid.
		/// </summary>
		private void CreateItemOptionsSource()
		{
			itemOptionsSource = new DataTable();
			itemOptionsSource.Columns.Add(ColumnSNo, typeof(int));
			itemOptionsSource.Columns.Add(ColumnId, typeof(int));
			itemOptionsSource.Columns.Add(ColumnOptionValue);
			itemOptionsSource.Columns.Add(ColumnOptionText);
		}
		
		
		/// <summary>
		/// Loads the item options data from an arraylist into a datatable
		/// </summary>
		/// <param name="itemOptions">Arraylist holding ItemOption objects</param>
		private void LoadItemOptions(ArrayList itemOptions)
		{
			int i=0;
			foreach(ItemOption option in itemOptions)
			{
				DataRow row = itemOptionsSource.NewRow();
				row[ColumnSNo] = ++i;
				row[ColumnId] = option.Id;
				row[ColumnOptionValue] = option.OptionValue;
				row[ColumnOptionText] = option.OptionText;
				itemOptionsSource.Rows.Add(row);
			}
		}

		
		/// <summary>
		/// Binds the options source to the grid
		/// </summary>
		private void BindItemOptions()
		{
			itemOptions.DataSource = itemOptionsSource;
			itemOptions.DataBind();
		}

		
		/// <summary>
		/// Updates the item options source with modified values from the grid
		/// </summary>
		private void UpdateOptions(bool validate)
		{
			for (int j=0, count=itemOptions.Items.Count; j<count ; ++j)
			{
				string newOptionValue = ((TextBox)itemOptions.Items[j].FindControl("itemOptionValue")).Text;
				if (validate && newOptionValue != string.Empty)
				{
					for(int i=0; i<j; ++i)
					{
						if (newOptionValue.ToUpper() == itemOptionsSource.Rows[i][ColumnOptionValue].ToString().ToUpper())
						{
							throw new Exception(string.Format("Save Values must be unique: The value '{0}' is duplicated.", newOptionValue));
						}
					}
				}
				itemOptionsSource.Rows[j][ColumnOptionValue] = newOptionValue;
				itemOptionsSource.Rows[j][ColumnOptionText] = ((TextBox)itemOptions.Items[j].FindControl("itemOptionText")).Text;
			}
		}
		
		
		/// <summary>
		/// Adds 5 empty rows to the item options grid
		/// </summary>
		private void AddEmptyRows()
		{
			UpdateOptions(false); //do not validate while adding new rows
			
			DataRow row;
			int initialRowCount = itemOptionsSource.Rows.Count;
			for (int i=initialRowCount; i<initialRowCount + 5; ++i)
			{
				row = itemOptionsSource.NewRow();
				row[ColumnSNo] = i;
				row[ColumnId] = 0;
				itemOptionsSource.Rows.Add(row);
			}
			BindItemOptions();
		}

		private void ToggleAnswerPanels()
		{
			if (refCodeAnswers.SelectedIndex == 0)
			{
				refCodeAnswersSection.Visible = true;
				explicitAnswersSection.Visible = false;
			}
			else
			{
				refCodeAnswersSection.Visible = false;
				explicitAnswersSection.Visible = true;
			}
		}
		#endregion

		#region Public methods
		/// <summary>
		/// Updates the options of the question with the values present in the grid. 
		/// </summary>
		/// <param name="itemOptionsList">The ItemOptions array of the QuestionnaireItem</param>
		/// <param name="questionnnaireItemId">Questionnaire Item Id</param>
		/// <returns>false if there are any duplicated option values</returns>
		public bool UpdateSource(ArrayList itemOptionsList, int questionnnaireItemId)
		{
			if (refCodeAnswers.SelectedIndex == 1)
			{
				if (currentItem.OptionsRefDomain != null && currentItem.OptionsRefDomain != string.Empty)
				{
					currentItem.OptionSourceChanged = true;
				}
				currentItem.OptionsRefDomain = null;
				UpdateOptions(true);
			
				for (int i=0, count=itemOptionsSource.Rows.Count; i<count; ++i)
				{
					ItemOption option = null;
					int id = int.Parse(itemOptionsSource.Rows[i][ColumnId].ToString());
					string optionValue = itemOptionsSource.Rows[i][ColumnOptionValue].ToString().Trim();
					if (id != 0)
					{
						foreach(ItemOption o in itemOptionsList)
						{
							if (o.Id == id)
							{
								option = o;
								break;
							}
						}
						if (optionValue == string.Empty)
							option.MarkForDelete = true; 
						else
						{
							option.OptionValue = optionValue;
							option.OptionText = itemOptionsSource.Rows[i][ColumnOptionText].ToString().Trim();
						}
					}
					else if (optionValue != string.Empty)
					{
						option = new ItemOption(cachePolicy);
						option.QuestionnaireItemId = questionnnaireItemId;
						option.OptionValue = optionValue;
						option.OptionText = itemOptionsSource.Rows[i][ColumnOptionText].ToString().Trim();
						itemOptionsList.Add(option);
					}
				}
			}
			else
			{
				if (refDomain.SelectedIndex == 0)
					throw new Exception("Please select a RefDomain.");
				if (currentItem.OptionsRefDomain == null || currentItem.OptionsRefDomain == string.Empty)
				{
					currentItem.OptionSourceChanged = true;
				}
				currentItem.OptionsRefDomain = refDomain.SelectedValue;
			}
			return true;
		}
		#endregion

		private void itemOptions_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
		{
			if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
			{
				if (isVersionDeployed)
					((TextBox)e.Item.FindControl("itemOptionValue")).Enabled = false;
			}
		}

		protected void OnRefCodeAnswersSelectedIndexChanged(object sender, System.EventArgs e)
		{
			ToggleAnswerPanels();
			ScriptManager.RegisterStartupScript(Page, Page.GetType(), "DependencyDeleteMessage","alert('Existing dependencies will be deleted upon clicking Save.');", true);
		}

	}
}
